#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "lm4f120h5qr.h"

/****************************************************************************
 * Initialize the GPIO for push buttons, UART and display
 ****************************************************************************/
void GPIOConfig(void)
{
	// Enable GPIO clock for A-F
	SYSCTL_RCGCGPIO_R |= 0x3F;	// GPIO_A: UART0, SPI, SW2, SW3
	// GPIO_B: LED DATA
	// GPIO_C: Color_EN, ROW_EN
	// GPIO_D: UART2, SW4, SW5
	// GPIO_E: ADC, UART5
	// GPIO_F: SW6, /OE

	// Set directions for GPIO Ports (0 = output, 1 = input)
	GPIO_PORTA_DIR_R &= 0x3F;	// Pin 6,7: input for SW2, SW3
	GPIO_PORTB_DIR_R |= 0xFF;	// Pin 0-7: output for LEDs
	GPIO_PORTC_DIR_R |= 0xF0;	// Pin 4-7: output for row and colors
	GPIO_PORTD_DIR_R &= 0xF3;	// Pin 4,5: input for SW4, SW5
	GPIO_PORTF_DIR_R &= 0xFD;	// Pin 1: input for SW6
	GPIO_PORTF_DIR_R |= 0x10;	// Pin 4: output for /OE

	// Set pullups for push buttons
	GPIO_PORTA_PUR_R |= 0xC0;	// Pin 6,7: pullup for SW2, SW3
	GPIO_PORTD_PUR_R |= 0x0C;	// Pin 4,5: pullup for SW4, SW5
	GPIO_PORTF_PUR_R |= 0x02;	// Pin 1: pullup for SW6

	// Set digital enable
	GPIO_PORTA_DEN_R |= 0xC3;	// Pin 6,7: SW2, SW3
	// Pin 1-2: UART0
	GPIO_PORTB_DEN_R |= 0xFF;
	GPIO_PORTC_DEN_R |= 0xF0;
	GPIO_PORTD_DEN_R |= 0xCC;	// Pin 4,5: SW4, SW5
	// Pin 6-7: UART2
	GPIO_PORTE_DEN_R |= 0x30;	// Pin 4-5: UART5
	GPIO_PORTF_DEN_R |= 0x12;	// Pin 4: SW6, /OE

	// Set the Alternate Function
	GPIO_PORTA_AFSEL_R |= 0x03;	// Pin 1-2: UART0
	GPIO_PORTD_AFSEL_R |= 0x0C;	// Pin 6-7: UART2
	GPIO_PORTE_AFSEL_R |= 0x0C;	// Pin 4-5: UART5

	// Set the Port Control Register
	GPIO_PORTA_PCTL_R |= (GPIO_PCTL_PA0_U0RX | GPIO_PCTL_PA1_U0TX);	// Pin 1-2: UART2
	GPIO_PORTD_PCTL_R |= (GPIO_PCTL_PD6_U2RX | GPIO_PCTL_PD7_U2TX);	// Pin 6-7: UART2
	GPIO_PORTE_PCTL_R |= (GPIO_PCTL_PE4_U5RX | GPIO_PCTL_PE5_U5TX);	// Pin 4-5: UART5
}

//*****************************************************************************
// Intialize ADC
//See page 384 of text book for details
//*****************************************************************************
void initializeADC(void)
{
	uint32_t delay = 10;

	// Enable ADC 
	SYSCTL_RCGCADC_R |= SYSCTL_RCGCADC_R0;

	while (delay != 0) {
		delay--;
	}

	GPIO_PORTE_DIR_R &= ~0x0C;	// Make GPIO_E_2/3 input
	GPIO_PORTE_AFSEL_R |= 0x0C;	// Enable alternate function
	GPIO_PORTE_DEN_R &= ~0x0C;	// Disable digital function
	GPIO_PORTE_AMSEL_R |= 0x0C;	// Enable analog function

	SYSCTL_RCGC0_R |= 0x00010000;	// Activate ADC0
	SYSCTL_RCGC0_R |= 0x00010000;	// Configure to 125K
	ADC0_SSPRI_R = 0x0123;	// Sequence 3 is highest priority
	ADC0_ACTSS_R &= ~0x0008;	// Disable sample sequencer 3
	ADC0_EMUX_R &= ~0xF000;	// Seq3 is software trigger
	ADC0_SSMUX3_R &= ~0x000F;	// Clear SS3 field

	// Set channel
	// ADC0_SSMUX3_R += 1;
	ADC0_SSCTL3_R = 0x0006;	// no TS0 D0, yes IE0 END0
	ADC0_IM_R &= ~0x0008;	// Disable interrupts
	ADC0_ACTSS_R |= 0x0008;	// Enable sample sequencer 3
}

void initializeUART0(void)
{
	
}

// *******************************************
// Configure GPIO PA5-PA2 for SPI
// *******************************************
void initializePortASpi0(void)
{
	// Set the 4 pins used for the SPI interface in the Digital Enable Register
	GPIO_PORTA_DEN_R |= 0x3C;	// Pin 2-5: SPI

	// Set the 4 pins used for the SPI interface in the Alternate Function Register
	GPIO_PORTA_AFSEL_R |= 0x3C;	// Pin 2-5: SPI

	// Set the Port Control Register ( See lm4f120h5qr.h starting at line 2045)
	GPIO_PORTA_PCTL_R |=
	    GPIO_PCTL_PA2_SSI0CLK | GPIO_PCTL_PA3_SSI0FSS |
	    GPIO_PCTL_PA4_SSI0RX | GPIO_PCTL_PA5_SSI0TX;
}
